﻿
Public Class [while]
    Inherits sentence

    Public Const [while] As String = "while"

    Private condition As value = Nothing
    Private para As paragraph = Nothing

    Private Sub New(ByVal icond As value, ByVal ipara As paragraph)
        condition = icond
        para = ipara
    End Sub

    Protected Friend Shared Shadows Function _isMeaningfulMark(ByVal c As Char) As Boolean
        Return [false](c)
    End Function

    Private Shared Function whilestart(ByVal s As String, ByVal index As Int64, ByRef inc As Int64) As Boolean
        If strsame(s, index, [while], 0, strlen([while])) Then
            inc = strlen([while])
            Return True
        Else
            Return False
        End If
    End Function

    Private Function finish(ByVal ctx As context) As ternary
        Dim v As bare_variable = Nothing
        If Not condition.invoke(ctx, v) Then
            Return ternary.unknown
        ElseIf v.false() Then
            Return ternary.true
        Else
            Return ternary.false
        End If
    End Function

    Protected Overrides Function invokeImpl(ByVal ctx As context) As Boolean
        assert(Not ctx Is Nothing, "ctx is nothing.")
        Dim f As ternary = ternary.unknown
        f = finish(ctx)
        While f = ternary.false
            If Not para.invoke(ctx) Then
                Return False
            End If

            f = finish(ctx)
        End While

        If f = ternary.unknown Then
            Return False
        Else
            Return True
        End If
    End Function

    Protected Shared Function parseImpl(ByVal input As String, ByRef index As Int64, _
                                        ByRef output As [while]) As Boolean
        If token(input, index, Nothing, AddressOf whilestart, AddressOf [false]) Then
            Dim condition As value = Nothing
            If value.parse(input, index, condition) Then
                Dim para As paragraph = Nothing
                If paragraph.parse(input, index, para) Then
                    output = New [while](condition, para)
                    Return True
                End If
            End If
        End If
        Return False
    End Function

    Protected Overrides Sub setsource(ByVal script As String, ByVal start As Long, ByVal [end] As Long)
        setsourceImpl([while] + character.blank + condition.scriptSource(), start, [end])
    End Sub

    Public Shared Shadows Function parse(ByVal input As String, ByRef index As Int64, _
                                         ByRef output As [while]) As Boolean
        Return parsebase(input, index, output, AddressOf parseImpl)
    End Function
End Class
